using Moq;
using NUnit.Framework;
using Tycho.Parser.Peg;

namespace Tycho.Parser.Tests.Peg {
    [TestFixture]
    public class LazyDynamicGrammarChoiceInsertionSpecification {
        private LazyDynamicGrammar Grammar;
        IProduction P1;
        IProduction P2;

        [SetUp]
        public void SetUp () {
            Grammar = new LazyDynamicGrammar ();
            P1 = new Mock<IProduction> ().Object;
            P2 = new Mock<IProduction> ().Object;
            Grammar.AddDynamicChoice (1, new [] { P1, P2 });
        }

        [Test]
        public void ShouldInsertBeforeAnotherProductionInMiddle () {
            IProduction p3 = new Mock<IProduction> ().Object;
            Grammar.InsertChoiceBefore (1, P2, p3);

            Assert.That (Grammar.GetChoices (1), Is.EqualTo (new [] { P1, p3, P2 }));
        }

        [Test]
        public void ShouldInsertIntoFirstPlace () {
            IProduction p3 = new Mock<IProduction> ().Object;
            Grammar.InsertChoiceBefore (1, P1, p3);

            Assert.That (Grammar.GetChoices (1), Is.EqualTo (new [] { p3, P1, P2 }));
        }

        [Test]
        public void ShouldInsertIntoFirstPlaceDirectly () {
            IProduction p3 = new Mock<IProduction> ().Object;
            Grammar.InsertChoiceFirst (1, p3);

            Assert.That (Grammar.GetChoices (1), Is.EqualTo (new [] { p3, P1, P2 }));
        }

        [Test]
        public void ShouldInsertProductionAfterAnotherInMiddle () {
            IProduction p3 = new Mock<IProduction> ().Object;
            Grammar.InsertChoiceAfter (1, P1, p3);

            Assert.That (Grammar.GetChoices (1), Is.EqualTo (new [] { P1, p3, P2 }));
        }

        [Test]
        public void ShouldInsertIntoLastPlace () {
            IProduction p3 = new Mock<IProduction> ().Object;
            Grammar.InsertChoiceAfter (1, P2, p3);

            Assert.That (Grammar.GetChoices (1), Is.EqualTo (new [] { P1, P2, p3 }));
        }

        [Test]
        public void ShouldInsertIntoLastPlaceDirectly () {
            IProduction p3 = new Mock<IProduction> ().Object;
            Grammar.InsertChoiceLast (1, p3);

            Assert.That (Grammar.GetChoices (1), Is.EqualTo (new [] { P1, P2, p3 }));
        }
    }
}